透過OpenAccessLinqDataSource快速排序、分頁
透過 OpenAccessLinqDataSource 繫結控制項,並啟動排序和分頁功能,非常簡單,而且會透過 LINQ 的 Take、Skip 轉為 Oracle 的 Rownum,進行夾擠法分頁。
OpenAccessLinqDataSource 實做分頁和排序功能,真的很好用,而且設定簡單,不過這篇文章當然不會這麼輕鬆就寫完,我們再整合前一篇設定過濾條件的方式,進行關鍵字查詢,裡面有一些小技巧和大家分享。
請在 Web 專案中加入一個 WebForm,我是命名為 OrderBy.aspx,然後放置:
● 一個 Label,名為 lblLog,用來呈現 OpenAccess ORM 實際執行的 Sql Script。
● 一個 Textbox,名為 txtKeyWord,關鍵字查詢的輸入欄位。
● 一個 Button,名為 btnKeyWork,送出關鍵字查詢動作。
● 一個 GridView,名為 gvList,顯示 Customers 資料,因為要排序和分頁,所以要設定 AllowSorting="True" AllowPaging="True" PageSize="5"。
● 一個 OpenAccessLinqDataSource,名為 oasrcCustomers,當然就是本篇的核心,用來存取底層資料庫。因為 OpenAccessLinqDataSource 預設就是 AutoPage=”true” AutoSort=”true”,所以不用特別再調整。
oasrcCustomers 的資料來源指向 Customers,我們選擇幾個欄位,要包含 CONTACTNAME,因為我們稍後要用此欄位篩選資料:
然後我們切換到【OrderBy】頁籤,選擇以 COUNTRY 逆排序(大到小),CITY 正排序,再故意多加一個沒有要查詢出來的 ADDRESS 做正排序,只是為了做測試會不會出錯而已:
接下來切換到【Where】頁籤,做如下的設定:
現在頁面的原始碼如下:
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="OrderBy.aspx.vb" Inherits="OALinqDataSourceWeb01.OrderBy" %>
<%@ Register Assembly="Telerik.OpenAccess.Web.40" Namespace="Telerik.OpenAccess.Web" TagPrefix="telerik" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>實做排序與分頁</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
<form id="form1" runat="server">
<div>
<asp:Label ID="lblLog" runat="server" />
<br />
連絡人姓名:<asp:TextBox ID="txtKeyWord" runat="server" placeholder="隨意輸入..." />
<asp:Button ID="btnKeyWork" runat="server" type="submit" CssClass="btn-mini btn-primary" Text="關鍵字查詢" />
<br />
<asp:GridView ID="gvList" runat="server" AutoGenerateColumns="False" DataSourceID="oasrcCustomers" AllowSorting="True" CssClass="table" AllowPaging="True" PageSize="5">
<Columns>
<asp:BoundField DataField="COUNTRY" HeaderText="COUNTRY" ReadOnly="True" SortExpression="COUNTRY"></asp:BoundField>
<asp:BoundField DataField="CITY" HeaderText="CITY" ReadOnly="True" SortExpression="CITY"></asp:BoundField>
<asp:BoundField DataField="CUSTOMERID" HeaderText="CUSTOMERID" ReadOnly="True" SortExpression="CUSTOMERID"></asp:BoundField>
<asp:BoundField DataField="COMPANYNAME" HeaderText="COMPANYNAME" ReadOnly="True" SortExpression="COMPANYNAME"></asp:BoundField>
<asp:BoundField DataField="CONTACTNAME" HeaderText="CONTACTNAME" ReadOnly="True" SortExpression="CONTACTNAME"></asp:BoundField>
</Columns>
</asp:GridView>
<telerik:OpenAccessLinqDataSource ID="oasrcCustomers" runat="server" ContextTypeName="OALinqDataSourceWeb01.NWModel" EntityTypeName="" OrderBy="COUNTRY desc, CITY, ADDRESS" ResourceSetName="Customers" Select="new (CITY, COMPANYNAME, CONTACTNAME, COUNTRY, CUSTOMERID)" Where="CONTACTNAME == @CONTACTNAME">
<WhereParameters>
<asp:ControlParameter ControlID="txtKeyWord" PropertyName="Text" DefaultValue="" Name="CONTACTNAME" Type="String"></asp:ControlParameter>
</WhereParameters>
</telerik:OpenAccessLinqDataSource>
</div>
</form>
其實這裡個問題,因為連絡人姓名我們是打算用關鍵字查詢,而不是完全相等(==),但在【Where】頁籤中,Openator 並沒有這個選項,所以我們只好先隨便選一個,再到程式碼中做修改:
所以我們就來調整 oasrcCustomers 的設定:
Where="CONTACTNAME == @CONTACTNAME"
改成
Where="CONTACTNAME.Contains(@CONTACTNAME)"
現在測試看看:
真是令人錯愕的訊息!Contains 當然存在於 String 中啊,不然 MSDN 寫假的喔:
所以答案一定不是錯誤訊息所顯示的內容。第一次遇到這問題,我爬了好多文章,最後其實解法很簡單,在 WhereParameters 的 ControlParameter 中,把 ConvertEmptyStringToNull 改為 false 即可(預設值為 true):
<telerik:OpenAccessLinqDataSource ID="oasrcCustomers" runat="server" ContextTypeName="OALinqDataSourceWeb01.NWModel" EntityTypeName="" OrderBy="COUNTRY desc, CITY, ADDRESS" ResourceSetName="Customers" Select="new (CITY, COMPANYNAME, CONTACTNAME, COUNTRY, CUSTOMERID)" Where="CONTACTNAME.Contains(@CONTACTNAME)">
<WhereParameters>
<asp:ControlParameter ControlID="txtKeyWord" PropertyName="Text" DefaultValue="" Name="CONTACTNAME" Type="String" ConvertEmptyStringToNull="false"></asp:ControlParameter>
</WhereParameters>
</telerik:OpenAccessLinqDataSource>
然後,當然我們還要到 aspx.vb 裡,把 Log String 抓出來:
Public Class OrderBy
Inherits System.Web.UI.Page
Private dbcxt As NWModel
Private tracer As MyNorthwindTraceListener
Private Sub OrderBy_Init(sender As Object, e As EventArgs) Handles Me.Init
If dbcxt Is Nothing Then
dbcxt = New NWModel()
End If
If tracer Is Nothing Then
tracer = New MyNorthwindTraceListener(New StringBuilder())
End If
End Sub
Private Sub OpenAccessLinqDataSource1_Selected(sender As Object, e As Telerik.OpenAccess.Web.OpenAccessLinqDataSourceStatusEventArgs) Handles oasrcCustomers.Selected
lblLog.Text = tracer.GetLogString()
End Sub
End Class
以下是執行結果:
Gif 連結:http://i.minus.com/ir4CThtncZbQu.Gif